<template>
    <view class="uni-collapse-item">
        <!-- onClick(!isOpen) -->
        <view @click="onClick(!isOpen)" class="uni-collapse-item__title"
            :class="{'is-open':isOpen &&titleBorder === 'auto' ,'uni-collapse-item-border':titleBorder !== 'none'}">
            <view class="uni-collapse-item__title-wrap">
                <slot name="title">
                    <view class="uni-collapse-item__title-box" :class="{'is-disabled':disabled}">
                        <image v-if="thumb" :src="thumb" class="uni-collapse-item__title-img" />
                        <text class="uni-collapse-item__title-text">{{ title }}</text>
                    </view>
                </slot>
            </view>

            <view v-if="showArrow"
                :class="{ 'uni-collapse-item__title-arrow-active': isOpen, 'uni-collapse-item--animation': showAnimation === true }"
                class="uni-collapse-item__title-arrow">
                <uni-icons :color="disabled?'#ddd':'#bbb'" size="14" type="bottom" />
            </view>
        </view>
        <view class="uni-collapse-item__wrap" :class="{'is--transition':showAnimation}"
            :style="{height: (isOpen?height:0) +'px'}">
            <view :id="elId" ref="collapse--hook" class="uni-collapse-item__wrap-content"
                :class="{open:isheight,'uni-collapse-item--border':border&&isOpen}">
                <slot></slot>
            </view>
        </view>

    </view>
</template>

<script>
    import uniIcons from '../../uni-icons/uni-icons.vue';
    // #ifdef APP-NVUE
    const dom = weex.requireModule('dom')
    // #endif
    /**
     * CollapseItem 折叠面板子组件
     * @description 折叠面板子组件
     * @property {String} title 标题文字
     * @property {String} thumb 标题左侧缩略图
     * @property {String} name 唯一标志符
     * @property {Boolean} open = [true|false] 是否展开组件
     * @property {Boolean} titleBorder = [true|false] 是否显示标题分隔线
     * @property {Boolean} border = [true|false] 是否显示分隔线
     * @property {Boolean} disabled = [true|false] 是否展开面板
     * @property {Boolean} showAnimation = [true|false] 开启动画
     * @property {Boolean} showArrow = [true|false] 是否显示右侧箭头
     */
    export default {
        components:{
            uniIcons
        },
        name: 'uniCollapseItem',
        props: {
            // 列表标题
            title: {
                type: String,
                default: ''
            },
            name: {
                type: [Number, String],
                default: ''
            },
            // 是否禁用
            disabled: {
                type: Boolean,
                default: false
            },
            // #ifdef APP-PLUS
            // 是否显示动画,app 端默认不开启动画，卡顿严重
            showAnimation: {
                type: Boolean,
                default: false
            },
            // #endif
            // #ifndef APP-PLUS
            // 是否显示动画
            showAnimation: {
                type: Boolean,
                default: true
            },
            // #endif
            // 是否展开
            open: {
                type: Boolean,
                default: false
            },
            // 缩略图
            thumb: {
                type: String,
                default: ''
            },
            // 标题分隔线显示类型
            titleBorder: {
                type: String,
                default: 'auto'
            },
            border: {
                type: Boolean,
                default: true
            },
            showArrow: {
                type: Boolean,
                default: true
            }
        },
        data() {
            // TODO 随机生生元素ID，解决百度小程序获取同一个元素位置信息的bug
            const elId = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
            return {
                isOpen: false,
                isheight: null,
                height: 0,
                elId,
                nameSync: 0
            }
        },
        watch: {
            open(val) {
                this.isOpen = val
                this.onClick(val, 'init')
            }
        },
        updated(e) {
            this.$nextTick(() => {
                this.init(true)
            })
        },
        created() {
            this.collapse = this.getCollapse()
            this.oldHeight = 0
            this.onClick(this.open, 'init')
        },
        // #ifndef VUE3
        // TODO vue2
        destroyed() {
            if (this.__isUnmounted) return
            this.uninstall()
        },
        // #endif
        // #ifdef VUE3
        // TODO vue3
        unmounted() {
            this.__isUnmounted = true
            this.uninstall()
        },
        // #endif
        mounted() {
            if (!this.collapse) return
            if (this.name !== '') {
                this.nameSync = this.name
            } else {
                this.nameSync = this.collapse.childrens.length + ''
            }
            if (this.collapse.names.indexOf(this.nameSync) === -1) {
                this.collapse.names.push(this.nameSync)
            } else {
                console.warn(`name 值 ${this.nameSync} 重复`);
            }
            if (this.collapse.childrens.indexOf(this) === -1) {
                this.collapse.childrens.push(this)
            }
            this.init()
        },
        methods: {
            init(type) {
                // #ifndef APP-NVUE
                this.getCollapseHeight(type)
                // #endif
                // #ifdef APP-NVUE
                this.getNvueHwight(type)
                // #endif
            },
            uninstall() {
                if (this.collapse) {
                    this.collapse.childrens.forEach((item, index) => {
                        if (item === this) {
                            this.collapse.childrens.splice(index, 1)
                        }
                    })
                    this.collapse.names.forEach((item, index) => {
                        if (item === this.nameSync) {
                            this.collapse.names.splice(index, 1)
                        }
                    })
                }
            },
            onClick(isOpen, type) {
                if (this.disabled) return
                this.isOpen = isOpen
                if (this.isOpen && this.collapse) {
                    this.collapse.setAccordion(this)
                }
                if (type !== 'init') {
                    this.collapse.onChange(isOpen, this)
                }
            },
            getCollapseHeight(type, index = 0) {
                const views = uni.createSelectorQuery().in(this)
                views
                    .select(`#${this.elId}`)
                    .fields({
                        size: true
                    }, data => {
                        // TODO 百度中可能获取不到节点信息 ，需要循环获取
                        if (index >= 10) return
                        if (!data) {
                            index++
                            this.getCollapseHeight(false, index)
                            return
                        }
                        // #ifdef APP-NVUE
                        this.height = data.height + 1
                        // #endif
                        // #ifndef APP-NVUE
                        this.height = data.height
                        // #endif
                        this.isheight = true
                        if (type) return
                        this.onClick(this.isOpen, 'init')
                    })
                    .exec()
            },
            getNvueHwight(type) {
                const result = dom.getComponentRect(this.$refs['collapse--hook'], option => {
                    if (option && option.result && option.size) {
                        // #ifdef APP-NVUE
                        this.height = option.size.height + 1
                        // #endif
                        // #ifndef APP-NVUE
                        this.height = option.size.height
                        // #endif
                        this.isheight = true
                        if (type) return
                        this.onClick(this.open, 'init')
                    }
                })
            },
            /**
             * 获取父元素实例
             */
            getCollapse(name = 'uniCollapse') {
                let parent = this.$parent;
                let parentName = parent.$options.name;
                while (parentName !== name) {
                    parent = parent.$parent;
                    if (!parent) return false;
                    parentName = parent.$options.name;
                }
                return parent;
            }
        }
    }
</script>

<style lang="scss">
    .uni-collapse-item {
        /* #ifndef APP-NVUE */
        box-sizing: border-box;

        /* #endif */
        &__title {
            /* #ifndef APP-NVUE */
            display: flex;
            width: 100%;
            box-sizing: border-box;
            /* #endif */
            flex-direction: row;
            align-items: center;
            transition: border-bottom-color .3s;

            // transition-property: border-bottom-color;
            // transition-duration: 5s;
            &-wrap {
                width: 100%;
                flex: 1;

            }

            &-box {
                padding: 0 15px;
                /* #ifndef APP-NVUE */
                display: flex;
                width: 100%;
                box-sizing: border-box;
                /* #endif */
                flex-direction: row;
                justify-content: space-between;
                align-items: center;
                height: 48px;
                line-height: 48px;
                background-color: #fff;
                color: #303133;
                font-size: 13px;
                font-weight: 500;
                /* #ifdef H5 */
                cursor: pointer;
                outline: none;

                /* #endif */
                &.is-disabled {
                    .uni-collapse-item__title-text {
                        color: #999;
                    }
                }

            }

            &.uni-collapse-item-border {
                border-bottom: 1px solid #ebeef5;
            }

            &.is-open {
                border-bottom-color: transparent;
            }

            &-img {
                height: 22px;
                width: 22px;
                margin-right: 10px;
            }

            &-text {
                flex: 1;
                font-size: 14px;
                /* #ifndef APP-NVUE */
                white-space: nowrap;
                color: inherit;
                /* #endif */
                /* #ifdef APP-NVUE */
                lines: 1;
                /* #endif */
                overflow: hidden;
                text-overflow: ellipsis;
            }

            &-arrow {
                /* #ifndef APP-NVUE */
                display: flex;
                box-sizing: border-box;
                /* #endif */
                align-items: center;
                justify-content: center;
                width: 20px;
                height: 20px;
                margin-right: 10px;
                transform: rotate(0deg);

                &-active {
                    transform: rotate(-180deg);
                }
            }


        }

        &__wrap {
            /* #ifndef APP-NVUE */
            will-change: height;
            box-sizing: border-box;
            /* #endif */
            background-color: #fff;
            overflow: hidden;
            position: relative;
            height: 0;

            &.is--transition {
                // transition: all 0.3s;
                transition-property: height, border-bottom-width;
                transition-duration: 0.3s;
                /* #ifndef APP-NVUE */
                will-change: height;
                /* #endif */
            }



            &-content {
                position: absolute;
                font-size: 13px;
                color: #303133;
                // transition: height 0.3s;
                border-bottom-color: transparent;
                border-bottom-style: solid;
                border-bottom-width: 0;

                &.uni-collapse-item--border {
                    border-bottom-width: 1px;
                    border-bottom-color: red;
                    border-bottom-color: #ebeef5;
                }

                &.open {
                    position: relative;
                }
            }
        }

        &--animation {
            transition-property: transform;
            transition-duration: 0.3s;
            transition-timing-function: ease;
        }

    }
</style>
